﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using eslib.nnp5.Matchers;

namespace eslib.nnp5.Waitors
{
    /// <summary>
    /// \n等待器
    /// </summary>
    public class NWaitor
    {
        public NWaitor()
        {
            matcher = new NMatcher();
            matcher.NMatcherMatchEvent += Matcher_NMatcherMatchEvent;

            reset();
        }

        private void reset()
        {
            lastMatch = new byte[0];
        }





        /// <summary>
        /// 等待对象
        /// </summary>
        private AutoResetEvent waitEvent = new AutoResetEvent(false);

        /// <summary>
        /// 最后一次匹配到的命令
        /// </summary>
        public byte[] lastMatch { get; private set; }



        NMatcher matcher;



        public void inStream(byte b)
        {
            matcher.inStream(b);
        }


        public void inStream(byte[] buf)
        {
            foreach (var b in buf)
            {
                inStream(b);
            }
        }


        private void Matcher_NMatcherMatchEvent(byte[] data)
        {
            lastMatch = data;

            //完成等待
            waitEvent.Set();

            NewLineEvent?.Invoke(data);
        }



        /// <summary>
        /// 可等待一行,同时与目标内容比较
        /// </summary>
        /// <param name="target">比较内容</param>
        /// <returns></returns>
        public async Task<bool> line(byte[] target)
        {
            return await Task.Run(() =>
            {
                waitEvent.WaitOne();    //等待Matcher的matchEvent事件（即等待下一个命令到达）

                //运行到这里,lastMatch一定已被赋值
                if (target.Length != lastMatch.Length) return false;        //匹配失败

                for (int i = 0; i < target.Length; i++)     //如果长度不匹配，上一行已经排除
                {
                    if (target[i] != lastMatch[i]) return false;        //字符不匹配,false
                }

                return true;        //到达这里，所有字符都匹配
            });
        }


        /// <summary>
        /// 可等待一行
        /// </summary>
        /// <returns></returns>
        public async Task line()
        {
            await Task.Run(() =>
            {
                waitEvent.WaitOne();    //等待Matcher的matchEvent事件（即等待下一个命令到达）
            });
        }


        /// <summary>
        /// 新行事件
        /// </summary>
        public event Action<byte[]> NewLineEvent;
    }
}
